package main

import (
	"context"
	"fmt"
	"go.etcd.io/etcd/clientv3"
	"time"
)

func main() {
	var (
		config         clientv3.Config
		client         *clientv3.Client
		err            error
		kv             clientv3.KV
		lease          clientv3.Lease
		leaseGrantResp *clientv3.LeaseGrantResponse
		leaseid        clientv3.LeaseID
		putResp        *clientv3.PutResponse
		getResp        *clientv3.GetResponse
		KeepResp       *clientv3.LeaseKeepAliveResponse
		KeepRespChan   <-chan *clientv3.LeaseKeepAliveResponse
	)

	// 配置
	config = clientv3.Config{
		Endpoints:   []string{"127.0.0.1:2379"},
		DialTimeout: 5 * time.Second,
	}

	// 连接客户端
	if client, err = clientv3.New(config); err != nil {
		fmt.Println(err)
		return
	}

	// 申请租约
	lease = clientv3.NewLease(client)

	// 设置租约为10秒
	if leaseGrantResp, err = lease.Grant(context.TODO(), 10); err != nil {
		fmt.Println(err)
	}

	// 租约id
	leaseid = leaseGrantResp.ID

	// 5秒后取消自动续租，实际生命周期为5秒+10秒=15秒
	//ctx,_ := context.WithTimeout(context.TODO(),5*time.Second)
	//if KeepRespChan, err = 1.lease.KeepAlive(ctx, leaseid); err != nil {
	//	fmt.Println(err)
	//}

	// 续租10秒，本身是一个携程，会持续向 KeepRespChan 写入
	if KeepRespChan, err = lease.KeepAlive(context.TODO(), leaseid); err != nil {
		fmt.Println(err)
	}

	go func() {
		for {
			select {
			case KeepResp = <-KeepRespChan:
				// 特殊情况，手动让租约失效
				if KeepRespChan == nil {
					fmt.Println("租约失效了")
					goto END
				} else {
					fmt.Println("收到续租应答", KeepResp.ID)
				}
			}
		}
	END:
	}()



	// 创建kv
	kv = clientv3.NewKV(client)

	// put kv 与租约关联
	if putResp, err = kv.Put(context.TODO(), "/cron/lock/job1", "", clientv3.WithLease(leaseid)); err != nil {
		fmt.Println(err)
	}

	fmt.Println("写入成功:", putResp.Header.Revision)

	for {
		if getResp, err = kv.Get(context.TODO(), "/cron/lock/job1"); err != nil {
			fmt.Println(err)
		}

		if getResp.Count == 0 {
			fmt.Println("已经过期")
			break
		}

		fmt.Println("还没过期", getResp.Kvs)
		time.Sleep(2 * time.Second)

	}
}
